using System;
using System.Collections.Generic;

namespace PropertyExpression.Common
{
    public static class EnumerableExtensions
    {
        /// <summary>
        /// This method is introduced to foreach variable closure.
        /// </summary>
        public static void ForEach<T>(this IEnumerable<T> enumerable, Action<T> action)
        {
            foreach (var item in enumerable) action(item);
        }

        public static IOption<TSource> Max<TSource>(
            this IEnumerable<TSource> source,
            Func<TSource, TSource, int> comparator)
        {
            var maxValue = default(TSource);
            var maxValueIsDefined = false;
            foreach (var item in source)
                if (maxValueIsDefined == false)
                {
                    maxValue = item;
                    maxValueIsDefined = true;
                }
                else if (comparator(maxValue, item) < 0)
                    maxValue = item;
            return maxValueIsDefined
                       ? maxValue.AsOption()
                       : Option.Nothing<TSource>();
        }

        public static IOption<TSource> Min<TSource>(
            this IEnumerable<TSource> source,
            Func<TSource, TSource, int> comparator)
        {
            return source.Max((source1, source2) => comparator(source2, source1));
        }
    }
}